/**
 *
 * Base naming rule:
 * The stuff start with "_" means private , end with "_" means protect ,
 * others mean public.
 *
 * All the member field should be private.
 *
 * Life cycle: (It's very important to know when we bind the event)
 * A widget will do this by order :
 * 1. $init
 * 2. set attributes (setters)
 * 3. rendering mold (@see mold/introcoach.js )
 * 4. call bind_ to bind the event to dom .
 *
 * this.deskop will be assigned after super bind_ is called,
 * so we use it to determine whether we need to update view
 * manually in setter or not.
 * If this.desktop exist , means it's after mold rendering.
 *
 */
introcoach.Introcoach = zk.$extends(zkmax.nav.Coachmark, {
	_clearColor: false,
	/*
	"left-top-aligned"，"top", "right-top-aligned",
	"left", "center"，"right"，
	"left-bottom-aligned","bottom" ,"right-bottom-aligned"
	 */

	setClearColor: function (val) {
		this._clearColor = val;
	},
	getClearColor: function () {
		return this._clearColor;
	},
	setSite: function (val) {
		var targetNode = this._getTargetDom(),
			targetLeft = zk(targetNode).revisedOffset()[0],
			targetTop = zk(targetNode).revisedOffset()[1] - 20,
			parent = this.$n('cave'),
			n = this.$n(),
			pHeight = parent.offsetHeight,
			pWidth = parent.offsetWidth,
			targetWidth = targetNode.offsetWidth,
			targetHeight = targetNode.offsetHeight,
			rightLeft = targetLeft + targetWidth,
			nLeft = targetLeft - pWidth,
			nTop = targetTop - pHeight,
			nBottom = targetTop + targetHeight,
			nRight = targetLeft + targetWidth;
		if (val === 'left-top-aligned') {
			jq(n).css("left", nLeft + 'px');
			jq(n).css("top", nTop + 'px');
		} else if (val === 'top') {
			jq(n).css("top", nTop + 'px');
			jq(n).css("left", targetLeft + 'px');
		} else if (val === 'right-top-aligned') {
			jq(n).css("top", nTop + 'px');
			jq(n).css("left", rightLeft + 'px');
		} else if (val === 'left') {
			jq(n).css("top", targetTop + 'px');
			jq(n).css("left", nLeft + 'px');
		} else if (val === 'center') {
			var left = targetLeft;
			if (targetWidth > pWidth)
				left = (targetWidth - pWidth) / 2 + targetLeft;
			var top = targetTop;
			if (targetHeight > pHeight)
				top = (targetHeight - pHeight) / 2 + targetTop;
			jq(n).css("top", top + 'px');
			jq(n).css("left", left + 'px');
		} else if (val === 'right') {
			jq(n).css("top", targetTop + 'px');
			jq(n).css("left", rightLeft + 'px');
		} else if (val === 'left-bottom-aligned') {
			jq(n).css("top", nBottom + 'px');
			jq(n).css("left", nLeft + 'px');
		} else if (val === 'bottom') {
			jq(n).css("top", nBottom + 'px');
			jq(n).css("left", targetLeft + 'px');
		} else if (val === 'right-bottom-aligned') {
			jq(n).css("top", nBottom + 'px');
			jq(n).css("left", nRight + 'px');
		}
	},
	bind_: function bind_() {
		var _this = this;
		this._zIndex = 18000;
		this.$supers(zkmax.nav.Coachmark, 'bind_', arguments);
		zWatch.listen({
			afterSize: this
		});

		if (this.isVisible()) {
			zk.afterMount(function () {
				if (zk.webkit && 'scrollRestoration' in history && history.scrollRestoration == 'auto') {
					// chrome scrollRestoration issue ZK-4407
					history.scrollRestoration = 'manual';
					setTimeout(function () {
						history.scrollRestoration = 'auto';
					}, _this.$class.SCROLL_RESTORATION_TIMEOUT); // turn back to 'auto' after 1000ms since we don't know when browser do scrollRestoration
				}

				_this._open();
			});
		}
	},
	_open: function _open() {
		var n = this.$n();

		if (n) {
			zk(n).makeVParent();

			this._syncPosition(n);

			this.setFloating_(true, {
				node: n
			});
			var topZIndex = 18000/*this.setTopmost()*/;
			n.style.zIndex = topZIndex > 0 ? topZIndex : 1;
			var uuid = this.uuid;

			this._highlightTarget();

			this.removeMask();
			var targetNode = this._getTargetDom();
			jq(targetNode).addClass('z-introcoach-layout');
			targetLeft = zk(targetNode).revisedOffset()[0],
				targetTop = zk(targetNode).revisedOffset()[1],
				targetWidth = targetNode.offsetWidth,
				targetHeight = targetNode.offsetHeight;
			var leftHtml = '<div id="' + uuid +
				'-mask-left" class="z-mask-layout z-modal-mask" style="z-index:17999;left:0px;top:0px;width:'
				+ targetLeft+'px"></div>';
			jq(document.body).append(leftHtml);
			var topHtml = '<div id="' + uuid +
				'-mask-top" class="z-mask-layout z-modal-mask" style="z-index:17999;left:'
				+ targetLeft + 'px;top:0px;height:'
				+ targetTop+'px;width:' + targetWidth + 'px"></div>';
			jq(document.body).append(topHtml);
			rightLeft = targetLeft + targetWidth;
			var rightHtml = '<div id="' + uuid +
				'-mask-right" class="z-mask-layout z-modal-mask" style="z-index:17999;left:'
				+ rightLeft + 'px;top:0px;"></div>';
			jq(document.body).append(rightHtml);
			bottomTop = targetTop + targetHeight;
			var bottomHtml = '<div id="' + uuid +
				'-mask-bottom" class="z-mask-layout z-modal-mask" style="z-index:17999;left:'
				+ targetLeft + 'px;top:'
				+ bottomTop +'px;width:' + targetWidth + 'px"></div>';
			jq(document.body).append(bottomHtml);
			jq(n).addClass(this.$s('open'));
			if (this._clearColor) {
				jq(this.$n('pointer')).css('border', 'none');
				jq(this.$n('cave')).css({'background-color': 'rgb(0,0,0,0)', 'box-shadow': 'none', 'position': 'absolute'});
			}
		}
	},
	_close: function _close() {
		var n = this.$n(),
			mask = this._mask;

		if (n) {
			this._restoreTarget();
			this.removeMask();
			zk(n).undoVParent();
			this.setFloating_(false);

			if (mask) {
				mask.destroy();
				this.clearCache();
				this._mask = null;
			}

			jq(n).removeClass(this.$s('open'));
		}
	},
	getUUID: function (val) {
		var uuid = jq(zk.$('$' + val)).attr('id');
		this.fire("onUUID", {data: [val, uuid]});
	},
	removeMask: function () {
		var elms = document.querySelectorAll('.z-mask-layout');
		elms.forEach(function (elm) {
			if (elm) {
				jq(elm).remove();
			} else
				console.log(elm);
		});
		var targets = document.querySelectorAll('.z-introcoach-layout');
		targets.forEach(function (target) {
			if (target) {
				jq(target).removeClass('z-introcoach-layout');
			} else
				console.log(elm);
		});
	},
});